import { _decorator, Component, instantiate, Node, Prefab, } from 'cc';
import { Player } from './Player';
import { Bullet } from './Bullet';
// @ts-ignore
import Colyseus from './colyseus-sdk/colyseus.js';
import { Box } from './Box';
const { ccclass, property } = _decorator;

@ccclass('StateEngine')
export class StateEngine extends Component {
    private static _instance: StateEngine

    public static getInstance(): StateEngine {
        if (!StateEngine._instance) {
            StateEngine._instance = new StateEngine()
        }
        return StateEngine._instance
    }

    @property(Prefab)
    public player: Prefab = null;
    public players: Map<string, Player> = new Map()
    @property(Prefab)
    public bullet: Prefab = null;
    public bullets: Map<string, Bullet> = new Map()
    @property(Prefab)
    public box: Prefab = null;
    public boxes: Map<string, Node> = new Map()

    public ip = 'localhost'// 服务器信息
    public port = '2567'// 端口
    public roomName = 'chat'// 房间名称
    public client: Colyseus.Client
    public room: Colyseus.Room
    async start() {
        StateEngine._instance = this
        this.client = new Colyseus.Client(`ws://${this.ip}:${this.port}`)
        const room = await this.client.joinOrCreate(this.roomName)
        this.room = room

        room.state.players.onAdd = this.onAddPlayer.bind(this)
        room.state.players.onRemove = this.onRemovePlayer.bind(this)
        room.state.bullets.onAdd = this.onAddBullet.bind(this)
        room.state.bullets.onRemove = this.onRemoveBullet.bind(this)
        room.state.textboxes.onAdd = this.onAddBox.bind(this)
        room.state.textboxes.onRemove = this.onRemoveBox.bind(this)
    }
    onAddBox(entite, key) {
        const box = instantiate(this.box)
        const tem = box.getComponent(Box)

        entite.onChange = (changes) => {
            changes.forEach((change) => {
                switch (change.field) {
                    case 'x':
                    case 'y':
                        tem.updatePosition(entite.x, entite.y);
                        break;
                    case 'direction':
                        tem.updateRotation(entite.direction);
                        break;
                    case 'hitCount': // 新增命中状态处理
                        tem.updateHitState(entite.hitCount);
                        break

                }
            });
        }

        box.parent = this.node
        this.boxes.set(key, box)
    }
    onRemoveBox(entite, key) { }
    onAddPlayer(entite, key) {
        const player = instantiate(this.player)
        const tem = player.getComponent(Player)
        tem.engine = this
        tem.player = player
        tem.playerEntity = entite
        tem.updatePosition(entite.x, entite.y)

        // 监听所有字段变化
        entite.onChange = (changes) => {
            changes.forEach((change) => {
                switch (change.field) {
                    case 'x':
                    case 'y':
                        tem.updatePosition(entite.x, entite.y);
                        break;
                    case 'direction':
                        tem.updateRotation(entite.direction);
                        break;
                }
            });
        };

        this.players.set(key, tem)
        player.parent = this.node
    }
    onRemovePlayer(entite, key) {
        const playerComp = this.players.get(key);
        if (playerComp) {
            playerComp.node.destroy();
            this.players.delete(key);
        }
    };
    onAddBullet(entite, key) {
        const bullet = instantiate(this.bullet)
        const tem = bullet.getComponent(Bullet)

        tem.updatePosition(entite.x, entite.y);
        tem.updateDirection(entite.direction);

        // 监听所有字段变化
        entite.onChange = (changes) => {
            changes.forEach((change) => {
                switch (change.field) {
                    case 'x':
                    case 'y':
                        tem.updatePosition(entite.x, entite.y);
                        break;
                    case 'direction':
                        tem.updateDirection(entite.direction);
                        break;
                }
            });
        }

        this.bullets.set(key, tem)
        bullet.parent = this.node
    }
    onRemoveBullet(entite, key) {
        const bulletComp = this.bullets.get(key);
        if (bulletComp) {
            bulletComp.node.destroy();
            this.bullets.delete(key);
        }
    };
    // 发送指令
    sendCommand(command: string, data: any) {
        // console.log('sendCommand', command, data)
        this.room.send(command, data)
    }
}

